﻿using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using System.Windows.Forms;
using WenSkin.Controls;

namespace WenSkin
{
    public partial class WenConfig
    {
        public partial class WenConfigForm : Forms.WenForm
        {
            public WenConfigForm(WenConfig wenConfig)
            {
                Initcom();
                Text += "系统配置设置 - " + wenConfig.ConfigName;
                config = wenConfig;

                ConfigLoad();
            }

            private void Initcom()
            {
                this.flow = new FlowLayoutPanel
                {
                    AutoScroll = true,
                    Dock = DockStyle.Fill,
                };
                this.Controls.Add(this.flow);

                WenButton WenImageButton = new WenButton()
                {
                    Text = "保存",
                    Dock = DockStyle.Bottom,
                };
                WenImageButton.Click += (s, e) =>
                {
                    config.Save();
                    WenConfigSaveChanged?.Invoke(this, new WenConfigEventArgs(this.config));
                    if (!string.IsNullOrWhiteSpace(SaveMessage))
                        MsgBoxInformation(SaveMessage);
                };
                this.Controls.Add(WenImageButton);
            }

            #region 私有属性

            private FlowLayoutPanel flow;
            private readonly WenConfig config;

            #endregion


            #region 公有属性

            public string SaveMessage { get; set; } = "保存成功！部分设置需要重启软件才能生效！";

            #endregion

            #region 委托事件

            [Category("Wen"), Description("按钮点击事件")]
            public event WenConfigItemClickEventHandler WenConfigItemClick;

            [Category("Wen"), Description("移除项")]
            public event WenConfigItemEventHandler WenConfigItemRemove;

            [Category("Wen"), Description("新增项")]
            public event WenConfigItemEventHandler WenConfigItemAdd;

            [Category("Wen"), Description("值变化")]
            public event WenConfigItemValueEventHandler WenConfigItemValueChanged;

            [Category("Wen"), Description("保存数据")]
            public event WenConfigEventHandler WenConfigSaveChanged;



            [ComVisible(true)]
            public delegate void WenConfigItemClickEventHandler(object sender, WenConfigItemClickEventArgs e);
            public class WenConfigItemClickEventArgs : WenConfigItemEventArgs
            {
                public WenConfigItemClickEventArgs(bool showTextBox, WenConfigGroup configXmlGroup, WenConfigItem configXmlItem) : base(configXmlGroup, configXmlItem)
                {
                    ShowTextBox = showTextBox;
                }

                public bool ShowTextBox { get; set; }
            }

            [ComVisible(true)]
            public delegate void WenConfigItemValueEventHandler(object sender, ConfigXmlItemValueEventArgs e);
            public class ConfigXmlItemValueEventArgs : WenConfigItemEventArgs
            {
                public ConfigXmlItemValueEventArgs(WenConfigGroup configXmlGroup, WenConfigItem configXmlItem, string changeValue) : base(configXmlGroup, configXmlItem)
                {
                    ChangeValue = changeValue;
                    State = true;
                }
                public string ChangeValue { get; set; }
                public bool State { get; set; }
            }

            [ComVisible(true)]
            public delegate void WenConfigItemEventHandler(object sender, WenConfigItemEventArgs e);
            public class WenConfigItemEventArgs : EventArgs
            {
                public WenConfigItemEventArgs(WenConfigGroup configGroup, WenConfigItem configItem)
                {
                    WenConfigGroup = configGroup;
                    WenConfigItem = configItem;
                }
                public WenConfigGroup WenConfigGroup { get; private set; }
                public WenConfigItem WenConfigItem { get; private set; }
            }

            [ComVisible(true)]
            public delegate void WenConfigEventHandler(object sender, WenConfigEventArgs e);
            public class WenConfigEventArgs : EventArgs
            {
                private readonly WenConfig wenConfig;

                public WenConfigEventArgs(WenConfig config)
                {
                    this.wenConfig = config;
                }

                public WenConfig WenConfig => wenConfig;
            }
            #endregion


            private void ConfigLoad()
            {
                flow.Controls.Clear();

                In(flow, this.config.Groups);

                void In(Control control, WenConfigGroupList groups)
                {
                    foreach (WenConfigGroup gr in groups)
                    {
                        GroupBox groupBox = new GroupBox()
                        {
                            Name = gr.Name,
                            Text = gr.Info,
                            AutoSize = true,
                            BackColor = Color.Transparent,
                            ForeColor = ControlHelper.ColorReverse(this.BackColor),
                            Visible = gr.Visible,
                        };

                        FlowLayoutPanel flow = new FlowLayoutPanel()
                        {
                            Dock = DockStyle.Fill,
                            AutoSize = true,
                            FlowDirection = FlowDirection.TopDown
                        };

                        FlowLayoutPanel flowItem = new FlowLayoutPanel()
                        {
                            Dock = DockStyle.Fill,
                            AutoSize = true,
                            FlowDirection = FlowDirection.TopDown
                        };
                        flow.Controls.Add(flowItem);

                        groupBox.Controls.Add(flow);
                        foreach (WenConfigItem item in gr.Items)
                        {
                            ItemAdd(item);
                        }

                        void ItemAdd(WenConfigItem item)
                        {
                            WenConfigItemControl configXmlItemControl = new WenConfigItemControl(gr, item);
                            configXmlItemControl.WenConfigItemClick += (s, e) =>
                            {
                                //事件准发即可
                                WenConfigItemClick?.Invoke(this, e);
                            };
                            configXmlItemControl.WenConfigItemRemove += (s, e) =>
                            {
                                //移除内容界面需要更改
                                WenConfigItemRemove?.Invoke(this, e);
                                gr.Items.Remove(item);
                                flowItem.Controls.Remove(configXmlItemControl);
                            };
                            configXmlItemControl.WenConfigItemValueChanged += (s, e) =>
                            {
                                WenConfigItemValueChanged?.Invoke(this, e);
                            };
                            flowItem.Controls.Add(configXmlItemControl);
                        }

                        //添加按钮
                        if (gr.AllowAdd)
                        {
                            flow.Controls.Add(AllowAddButton(gr, ItemAdd));
                        }

                        control.Controls.Add(groupBox);
                        if (gr.Groups.Count > 0)
                        {
                            In(flow, gr.Groups);
                        }
                    }
                }

            }

            #region 增添一个添加一项按钮
            private WenButton AllowAddButton(WenConfigGroup group, Action<WenConfigItem> action)
            {
                WenButton button = new WenButton()
                {
                    Text = "新增一项",
                    Size = new Size(500, 26)
                };
                button.Click += (s, e) =>
                {
                    WenConfigItem configXmlItem = new WenConfigItem(group.Items)
                    {
                        Name = $"{group.Name}{group.Items.Count + 1:000}",
                        Ecc = false,
                        ReadOnly = false,
                        Delete = true,
                        Value = "",
                    };

                    Forms.WenForm form = new Forms.WenForm()
                    {
                        StartPosition = FormStartPosition.CenterScreen,
                        Size = new Size(300, 100),
                        Text = "请输入名称"
                    };

                    TextBox textBox = new TextBox()
                    {
                        Text = "新增名称",
                        Dock = DockStyle.Fill,
                        ScrollBars = ScrollBars.Both,
                        WordWrap = false
                    };

                    WenButton button1 = new WenButton()
                    {
                        Text = "确定",
                        Dock = DockStyle.Bottom,
                    };
                    button1.Click += (sx, ex) =>
                    {
                        WenConfigItemAdd?.Invoke(this, new WenConfigItemEventArgs(group, configXmlItem));
                        configXmlItem.Info = textBox.Text;
                        group.Items.Add(configXmlItem);
                        action(configXmlItem);
                        form.Dispose();
                    };

                    form.Controls.Add(textBox);
                    form.Controls.Add(button1);
                    form.ShowDialog();
                };
                return button;
            }

            #endregion

            #region 单项样式

            [ToolboxItem(false)]
            private class WenConfigItemControl : WenControl
            {
                public WenConfigItemControl(WenConfigGroup gr, WenConfigItem item) : base()
                {
                    if (item.ComboBox)
                    {
                        this.Visible = item.Visible;
                        comboBox = new WenLableComboBox()
                        {
                            Dock = DockStyle.Fill,
                            Name = item.Name,
                            TextLable = item.Info,
                            DropDownStyle = item.ReadOnly ? ComboBoxStyle.DropDownList : ComboBoxStyle.DropDown,
                        };
                        comboBox.Items.AddRange(item.Items.ToArray());

                        if (item.Tip != null && item.Tip.Length != 0)
                        {
                            foreach (Control c in comboBox.Controls)
                            {
                                tip.SetToolTip(c, item.Tip);
                            }
                        }
                        comboBox.Text = item.Value;

                        comboBox.TextChanged += (s, e) =>
                        {
                            //值改变响应事件
                            ConfigXmlItemValueEventArgs configXmlItemValueEventArgs = new ConfigXmlItemValueEventArgs(gr, item, comboBox.Text);
                            WenConfigItemValueChanged?.Invoke(this, configXmlItemValueEventArgs);

                            if (configXmlItemValueEventArgs.State)
                                item.Value = comboBox.Text;
                        };

                        comboBox.Size = new Size(450, comboBox.Height);
                        this.Controls.Add(comboBox);

                        //移除项目 按钮
                        if (gr.AllowAdd && item.Delete)
                        {
                            WenButton button = new WenButton()
                            {
                                Image = Properties.Resources.close,
                                ImageSize = new Size(16, 16),
                                Dock = DockStyle.Right,
                                Size = new Size(20, 20)
                            };
                            button.Click += (s, e) =>
                            {
                                if (this.MsgBoxAsterisk("删除不可逆，是否删除"))
                                {
                                    WenConfigItemRemove?.Invoke(this, new WenConfigItemEventArgs(gr, item));
                                }
                            };
                            this.Controls.Add(button);
                        }
                        this.Size = new Size(500, comboBox.Height + 3);
                    }
                    else
                    {
                        this.Visible = item.Visible;
                        textBox = new WenLableTextBox()
                        {
                            Dock = DockStyle.Fill,
                            Name = item.Name,
                            TextLable = item.Info,
                            Text = item.Value,
                            Password = item.Ecc,
                            ReadOnly = item.ReadOnly,
                        };
                        //按钮点击事件
                        textBox.ButtonClick += (s, e) =>
                        {
                            WenConfigItemClickEventArgs ex = new WenConfigItemClickEventArgs(e.ShowTextBox, gr, item);
                            WenConfigItemClick?.Invoke(this, ex);
                            e.ShowTextBox = ex.ShowTextBox;
                        };

                        if (item.Tip != null && !string.IsNullOrWhiteSpace(item.Tip))
                        {
                            foreach (Control c in textBox.Controls)
                            {
                                tip.SetToolTip(c, item.Tip);
                            }
                        }

                        textBox.Size = new Size(450, textBox.Height);
                        textBox.TextBeforeChanged += (s, e) =>
                        {

                            //值改变响应事件
                            ConfigXmlItemValueEventArgs configXmlItemValueEventArgs = new ConfigXmlItemValueEventArgs(gr, item, textBox.Text);

                            WenConfigItemValueChanged?.Invoke(this, configXmlItemValueEventArgs);

                            e.State = configXmlItemValueEventArgs.State;
                            if (configXmlItemValueEventArgs.State)
                                item.Value = textBox.Text;
                        };
                        this.Controls.Add(textBox);

                        //移除项目 按钮
                        if (gr.AllowAdd && item.Delete)
                        {
                            WenButton button = new WenButton()
                            {
                                Image = Properties.Resources.close,
                                ImageSize = new Size(16, 16),
                                Dock = DockStyle.Right,
                                Size = new Size(20, 20)
                            };
                            button.Click += (s, e) =>
                            {
                                if (this.MsgBoxAsterisk("删除不可逆，是否删除"))
                                {
                                    WenConfigItemRemove?.Invoke(this, new WenConfigItemEventArgs(gr, item));
                                }
                            };
                            this.Controls.Add(button);
                        }
                        this.Size = new Size(500, textBox.Height);
                    }
                }

                #region 私有属性

                private readonly ToolTip tip = new ToolTip();
                private WenLableTextBox textBox;
                private WenLableComboBox comboBox;
                #endregion

                #region 委托事件

              [Category("Wen"), Description("按钮点击事件")]
                public event WenConfigItemClickEventHandler WenConfigItemClick;

                [Category("Wen"), Description("移除一项")]
                public event WenConfigItemEventHandler WenConfigItemRemove;

                [Category("Wen"), Description("值发生变化")]
                public event WenConfigItemValueEventHandler WenConfigItemValueChanged;

                #endregion

                public new void Focus()
                {
                    textBox?.Focus();
                    comboBox?.Focus();
                }
            }

            #endregion

        }
    }
}
